﻿using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace DaHuaSnapShot
{
   public class CameraSnapshot
    {
        // 客户端池，按 username:password 复用 HttpClient（包含相应的 handler）
        private static readonly ConcurrentDictionary<string, HttpClient> _clientPool = new ConcurrentDictionary<string, HttpClient>();

        private HttpClient GetOrCreateClient(string username, string password)
        {
            string key = $"{username}:{password}";
            return _clientPool.GetOrAdd(key, k =>
            {
                var handler = new HttpClientHandler
                {
                    Credentials = new NetworkCredential(username, password),
                    PreAuthenticate = true,
                    UseDefaultCredentials = false
                };

                var client = new HttpClient(handler);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
                client.Timeout = TimeSpan.FromSeconds(30);
                return client;
            });
        }

        /// <summary>
        /// 使用Digest认证从摄像头获取快照并保存到文件
        /// </summary>
        /// <param name="url">摄像头快照URL</param>
        /// <param name="username">摄像头账号</param>
        /// <param name="password">摄像头密码</param>
        /// <param name="savePath">保存路径</param>
        /// <returns>是否成功</returns>
        public async Task<bool> GetSnapshotAsync(string url, string username, string password, string savePath)
        {
            try
            {
                var client = GetOrCreateClient(username, password);

                const int maxAttempts = 3;
                int attempt = 0;
                while (attempt < maxAttempts)
                {
                    attempt++;
                    try
                    {
                        NLogService.logger.Info($"正在请求: {url} (尝试 {attempt})");
                        using (var response = await client.GetAsync(url))
                        {
                            response.EnsureSuccessStatusCode();

                            // 读取响应内容并保存到文件（覆盖写入）
                            using (var stream = await response.Content.ReadAsStreamAsync())
                            using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None))
                            {
                                await stream.CopyToAsync(fileStream);
                            }

                            NLogService.logger.Info($"快照已保存到: {savePath}");
                            return true;
                        }
                    }
                    catch (HttpRequestException ex)
                    {
                        NLogService.logger.Error($"HTTP请求错误（尝试 {attempt}）：{ex.Message}");
                        if (ex.InnerException != null)
                        {
                            NLogService.logger.Error($"内部错误: {ex.InnerException.Message}");
                        }

                        if (attempt >= maxAttempts)
                        {
                            return false;
                        }

                        // 指数退避
                        await Task.Delay(500 * attempt);
                    }
                    catch (TaskCanceledException ex)
                    {
                        // 可能是超时
                        NLogService.logger.Error($"请求超时（尝试 {attempt}）：{ex.Message}");
                        if (attempt >= maxAttempts)
                        {
                            return false;
                        }

                        await Task.Delay(500 * attempt);
                    }
                }

                return false;
            }
            catch (Exception ex)
            {
                NLogService.logger.Error($"发生错误: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 同步版本的获取快照方法
        /// </summary>
        /// <param name="url">摄像头快照URL</param>
        /// <param name="username">摄像头账号</param>
        /// <param name="password">摄像头密码</param>
        /// <param name="savePath">保存路径</param>
        /// <returns>是否成功</returns>
        public bool GetSnapshot(string url, string username, string password, string savePath)
        {
            // 使用Task.Run来执行异步方法并等待完成
            return Task.Run(() => GetSnapshotAsync(url, username, password, savePath)).Result;
        }
    }
}
